package net.imagine.core.crop;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import net.imagine.core.ImageInfo;
import net.imagine.core.ImageProcessResult;
import net.imagine.core.ImageProcessTask;
import net.imagine.core.ImageProcessTemplate;
import net.imagine.core.ResultState;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class ImageCropTemplate extends ImageProcessTemplate  {
	private static final Log logger = LogFactory.getLog(ImageCropTemplate.class);
	
	@SuppressWarnings("unchecked")
	public <T extends ImageProcessResult> T processImage(String imagePath, ImageProcessTask processTask)
			throws IOException {
		ImageCropTask task = null;
		if (processTask instanceof ImageCropTask) {
			task = (ImageCropTask) processTask;
		}
		if (task == null) {
			logger.warn("task is not a image crop task");
			T result = (T) new ImageProcessResult(ResultState.UNKOWN_FAILED);
			result.setOriginalFilename(processTask.getFilename());
			return result;
		}
		
		ResultState state = ResultState.UNKOWN_FAILED;
		List<String> localFileList = new ArrayList<String>(2);
		String[] fileKeys = new String[1];
		
		//第一步，获取图片并保存到本地临时文件
		File localSrcFile = generateLocalFile(imagePath, task, localFileList);
		if(localSrcFile == null) {
			T result = (T) new ImageProcessResult(ResultState.STORE_FAILED);
			result.setOriginalFilename(processTask.getFilename());
			return result;
		}
		String srcURL = localSrcFile.getPath();
		ImageInfo info = operations.showImageInfo(srcURL);
		if(info == null) {
			return processResult(ResultState.NOT_IMAGE, task, fileKeys, null);
		}
		String ext = info.getExt();
		int height = info.getHeight();
		int width = info.getWidth();
		//第二步，生成本地目标文件
		File destImageFile = generateDestFile(imagePath, task, ext);
		//第三步，剪切图片
		
		String destURL = destImageFile.getPath();
		//计算各坐标
		int x = 0;
		if(task.getOffsetX() != null) {
			x = task.getOffsetX();
		}
		int y = 0;
		if(task.getOffsetY() != null) {
			y = task.getOffsetY();
		}
		int cropSize = Math.min(height, width);
		if(task.getCropSize() != null) {
			cropSize = task.getCropSize();
		}
		int finalSize = cropSize;
		if(task.getFinalSize() != null) {
			finalSize = task.getFinalSize();
		}	
			
		if(task.isNeedResize() && cropSize != finalSize) {
			state = operations.cropAndResizeImage(srcURL, destURL, x, y, cropSize, finalSize);
		} else {
			state = operations.cropImage(srcURL, destURL, x, y, cropSize);
		}
		if(state != ResultState.SUCCESS) {
			return processResult(state, task, fileKeys, info);
		}
		//第四步，存储剪切后的图片
		state = storeCroppedFile(destURL, fileKeys, task, localFileList);
		if(state != ResultState.SUCCESS) {
			return processResult(state, task, fileKeys, info);
		}
		T result = processResult(state, task, fileKeys, info);
		// 第五步、删除文件或者执行图片的下一环节操作
		if (this.nextProcessor != null) {
			processTask.setLocalStorePath(destImageFile.getPath());
			return nextProcessor.processImage(imagePath, processTask);
		} else {
			deleteFiles(localFileList);
		}
		return result;
	}
	
	protected abstract void deleteFiles(List<String> localFileList);

	protected abstract File generateDestFile(String imagePath, ImageCropTask task, String ext);

	protected abstract File generateLocalFile(String basePath, ImageCropTask task, List<String> localFileList);

	protected abstract <T extends ImageProcessResult> T processResult(ResultState state, ImageCropTask task, String[] fileKeys, ImageInfo info);

	protected abstract ResultState storeCroppedFile(String destFile, String[] fileKeys, ImageCropTask task, List<String> localFileList);
}
